import { ref } from 'vue'
import { defineStore } from 'pinia'
import type { RouteRecordRaw } from 'vue-router'
import { getRoutesApi } from '@/server/menus'
import { store } from '@/store'
import { constantRoutes } from '@/router'

const modules = import.meta.glob('../../views/**/**.vue')
const Layout = () => import('@/layout/index.vue')

/**
 * @description 使用meta.role判断当前用户是否有权限
 * @param roles 用户角色集合
 * @param route 路由
 * @returns
 */
const hasPermission = (roles: string[], route: RouteRecordRaw) => {
  if (route.meta && route.meta.roles) {
    // 角色【超级管理员】拥有所有权限，忽略校验
    if (roles.includes('ROOT')) {
      return true
    }
    return roles.some((role) => {
      if (route.meta?.roles) {
        return route.meta.roles.includes(role)
      }
      return false
    })
  }
  return false
}

/**
 * @description 递归过滤有权限的异步(动态)路由
 * @param routes 接口返回的异步(动态)路由
 * @param roles 用户角色集合
 * @returns 返回用户有权限的异步(动态)路由
 */
const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
  const asyncRoutes: RouteRecordRaw[] = []

  routes.forEach((route) => {
    const tmpRoute = { ...route }
    if (!route.name) {
      tmpRoute.name = route.path
    }
    // 判断用户(角色)是否有该路由的访问权限
    if (hasPermission(roles, tmpRoute)) {
      if (tmpRoute.component?.toString() == 'Layout') {
        tmpRoute.component = Layout
      } else {
        const component = modules[`../../views/${tmpRoute.component}.vue`]
        if (component) {
          tmpRoute.component = component
        } else {
          tmpRoute.component = modules['../../views/error-page/404.vue']
        }
      }
      if (tmpRoute.children) {
        tmpRoute.children = filterAsyncRoutes(tmpRoute.children, roles)
      }
      asyncRoutes.push(tmpRoute)
    }
  })

  return asyncRoutes
}

export const usePermissionStore = defineStore('permission', () => {
  const routes = ref<RouteRecordRaw[]>([])

  const setRoutes = (accessRoutes: RouteRecordRaw[]) => {
    routes.value = constantRoutes.concat(accessRoutes)
  }

  /**
   * 生成动态路由
   *
   * @param roles 用户角色集合
   * @returns
   */
  const generateRoutes = async (roles: string[]) => {
    try {
      const res = await getRoutesApi()
      const { data: asyncRoutes } = res
      // 根据角色获取有访问权限的路由
      const accessRoutes = filterAsyncRoutes(asyncRoutes, roles)
      // 设置路由表
      setRoutes(accessRoutes)
      return accessRoutes
    } catch (error) {
      return Promise.reject(error)
    }
  }

  return {
    routes,
    setRoutes,
    generateRoutes
  }
})

export function usePermissionStoreHook() {
  return usePermissionStore(store)
}
